home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 2 / Meeting Pearls Vol. II (1995)(GTI - Schatztruhe)[!].iso / Pearls / dev / Oberon4Amiga / Dialogs / Dialog.Mod (.txt) < prev    next >
Oberon Text  |  1994-11-28  |  20KB  |  460 lines

  1. Syntax10.Scn.Fnt
  2. Syntax10i.Scn.Fnt
  3. StampElems
  4. Alloc
  5. 8 Nov 94
  6. Syntax10b.Scn.Fnt
  7. MODULE Dialog;    
  8.     (**  extended version by Markus Knasm
  9. ller 25.May.94 -  
  10.     IMPORT DialogFrames, Dialogs, DialogButtons, Display, Display1, Files, In, Input, MenuViewers, 
  11.         TextFrames, Texts, Oberon, Printer, Viewers;
  12.     (* DialogText must be loaded before, because setting of o.Edit and o.Update must be before Editing is possible *)
  13.     CONST 
  14.         ML =2; MM = 1; MR = 0; CRSU = 0C1X; CRSD = 0C2X; CRSR = 0C3X; CRSL = 0C4X;
  15.         editMenu = "System.Close  System.Copy  System.Grow  Dialog.Store "; 
  16.         markW = 5;
  17.     VAR 
  18.         reticule*:Oberon.Marker;  (** used as caret *)
  19.         w0: Texts.Writer;  
  20.         DW, DH, CL: INTEGER;
  21.         nx, ny, X1, X0, Y1, Y0: INTEGER;
  22.     PROCEDURE Min (x: INTEGER; y:INTEGER): INTEGER;
  23.     BEGIN IF x < y THEN RETURN x ELSE RETURN y END
  24.     END Min;
  25.     PROCEDURE Open*;     (** name | ^ *)
  26.     (** opens a dialog viewer and displays the dialog from file name *)
  27.         VAR x, y, res: INTEGER; p: Dialogs.Panel; name: ARRAY 64 OF CHAR; 
  28.     BEGIN
  29.         In.Open; In.Name (name);
  30.         IF In.Done THEN         
  31.             Oberon.AllocateUserViewer (Oberon.Mouse.X, x, y);
  32.             DialogFrames.OpenPanel (name, x, y, p);        
  33.         END 
  34.     END Open;
  35.     PROCEDURE SetInitCmd*;    (** cmd | ^ *)
  36.     (** sets the command of the marked dialog to cmd *)
  37.         VAR x, y: INTEGER; p: Dialogs.Panel; cmd: ARRAY 64 OF CHAR; 
  38.     BEGIN 
  39.         In.Open; In.Name (cmd); 
  40.         IF In.Done THEN Dialogs.res := Dialogs.ok ELSE Dialogs.res := Dialogs.wrongInput END;
  41.         IF Dialogs.res = Dialogs.ok THEN
  42.             DialogFrames.GetCaretPosition (p, x, y);
  43.             IF p # NIL THEN p.SetCmd (cmd) ELSE Dialogs.res := Dialogs.noPanelSelected END
  44.         END;
  45.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  46.     END SetInitCmd;
  47.     PROCEDURE SetName*;    (** name | ^ *)
  48.     (** sets the name of the object under the caret to name *)
  49.         VAR o: Dialogs.Object; p: Dialogs.Panel; name: ARRAY 64 OF CHAR;  
  50.     BEGIN 
  51.         In.Open; In.Name (name); 
  52.         IF In.Done THEN Dialogs.res := Dialogs.ok ELSE Dialogs.res := Dialogs.wrongInput END;
  53.         IF Dialogs.res = Dialogs.ok THEN
  54.             DialogFrames.FindObject (o, p);
  55.             IF Dialogs.res = Dialogs.ok THEN o.SetName (name) END
  56.         END;
  57.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  58.     END SetName;
  59.     PROCEDURE SetCmd*;    (** cmd | ^ *)
  60.     (** sets the command of the object under the caret to cmd *)
  61.         VAR o: Dialogs.Object; p: Dialogs.Panel; cmd: ARRAY 64 OF CHAR; 
  62.     BEGIN 
  63.         In.Open; In.Name (cmd); 
  64.         IF In.Done THEN Dialogs.res := Dialogs.ok ELSE Dialogs.res := Dialogs.wrongInput END;
  65.         IF Dialogs.res = Dialogs.ok THEN
  66.             DialogFrames.FindObject (o, p);
  67.             IF Dialogs.res = Dialogs.ok THEN o.SetCmd (cmd) END
  68.         END;
  69.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  70.     END SetCmd;
  71.     PROCEDURE SetPar*;    (** par | ^ *)
  72.     (** sets the parameter of the item at the caret to par *)
  73.         VAR o: Dialogs.Object; p: Dialogs.Panel; par: ARRAY 64 OF CHAR; 
  74.     BEGIN 
  75.         In.Open; In.Name (par); 
  76.         IF In.Done THEN Dialogs.res := Dialogs.ok ELSE Dialogs.res := Dialogs.wrongInput END;
  77.         IF Dialogs.res = Dialogs.ok THEN
  78.             DialogFrames.FindObject (o, p);
  79.             IF Dialogs.res = Dialogs.ok THEN o.SetPar (par) END
  80.         END;
  81.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  82.     END SetPar;
  83.     PROCEDURE SetDim*;    (** x y w h | ^ *)
  84.     (** sets the lower left coordinates of the object under the caret to x and y, the width to w and the height to h *)
  85.         VAR x, y, w, h: INTEGER; o: Dialogs.Object; p: Dialogs.Panel;  
  86.     BEGIN
  87.         In.Open; In.Int (x); Dialogs.res := Dialogs.ok; 
  88.         IF ~ In.Done THEN Dialogs.res := Dialogs.wrongInput END;
  89.         In.Int (y); IF ~ In.Done THEN Dialogs.res := Dialogs.wrongInput END;
  90.         In.Int (w); IF ~ In.Done THEN Dialogs.res := Dialogs.wrongInput END;
  91.         In.Int (h); IF ~ In.Done THEN Dialogs.res := Dialogs.wrongInput END;
  92.         IF Dialogs.res = Dialogs.ok THEN
  93.             DialogFrames.FindObject (o, p);
  94.             IF  Dialogs.res = Dialogs.ok THEN o.SetDim (x, y, w, h, FALSE) END
  95.         END;
  96.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  97.     END SetDim;
  98.     PROCEDURE AlignSelected*;    (** dir | ^ *)
  99.     (** aligns the selected objects so that they have the same left, right, top or bottom coordinates *)
  100.         VAR dir: CHAR; x, y: INTEGER; p: Dialogs.Panel; name: ARRAY 64 OF CHAR;
  101.     BEGIN
  102.         In.Open; In.Name (name); Dialogs.res := Dialogs.ok;
  103.         IF In.Done THEN dir := name[0] END; 
  104.         IF (dir # "R") & (dir # "L") & (dir # "U") & (dir # "D") THEN
  105.             Dialogs.res := Dialogs.wrongInput
  106.         ELSE 
  107.             DialogFrames.GetCaretPosition (p, x, y);
  108.             IF p # NIL THEN
  109.                 p.AlignSelected (dir)
  110.             ELSE
  111.                 Dialogs.res := Dialogs.noPanelSelected
  112.             END
  113.         END;
  114.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  115.     END AlignSelected;
  116.     PROCEDURE RegulateDistance*;    (** dir | ^ *)
  117.     (** regulates the distance between the selected objects *)
  118.         VAR dir:  CHAR; i, j: INTEGER; p: Dialogs.Panel; name: ARRAY 64 OF CHAR;
  119.     BEGIN
  120.         In.Open; In.Name (name); Dialogs.res := Dialogs.ok;
  121.         IF In.Done THEN dir := name [0] END;    
  122.         IF  (dir # "R") & (dir #"L") & (dir # "U") & (dir # "D")
  123.             THEN Dialogs.res := Dialogs.wrongInput
  124.         ELSE
  125.             DialogFrames.GetCaretPosition (p, i, j);
  126.             IF p # NIL THEN
  127.                 p.RegulateDistance (dir)
  128.             ELSE 
  129.                 Dialogs.res := Dialogs.noPanelSelected
  130.             END
  131.         END;
  132.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  133.     END RegulateDistance;
  134.     PROCEDURE GetDim*;
  135.     (** writes the coordinates of the lower left corner, the width and the height 
  136.         of the object under the caret to the log viewer *)
  137.         VAR x, y, w, h: INTEGER; o: Dialogs.Object; p: Dialogs.Panel;
  138.     BEGIN
  139.         DialogFrames.FindObject (o, p);
  140.         IF Dialogs.res = Dialogs.ok THEN 
  141.             o.GetDim (x, y, w, h);
  142.             Texts.WriteString (w0, "Coor: "); Texts.WriteInt (w0, x, 5); Texts.WriteInt (w0, y, 5); 
  143.             Texts.WriteLn (w0); Texts.WriteString (w0, "Wide and Height: "); Texts.WriteInt (w0, w, 5); 
  144.             Texts.WriteInt (w0, h, 5); Texts.WriteLn (w0); Texts.Append (Oberon.Log, w0.buf)
  145.         ELSE
  146.             Dialogs.Error ("Dialog") 
  147.         END
  148.     END GetDim;    
  149.     PROCEDURE GetName*;
  150.     (** writes the name of the object under the caret to the log viewer *)
  151.         VAR o: Dialogs.Object; p: Dialogs.Panel; name: ARRAY 32 OF CHAR;
  152.     BEGIN
  153.         DialogFrames.FindObject (o, p);
  154.         IF Dialogs.res = Dialogs.ok THEN
  155.             COPY (o.name, name); Texts.WriteString (w0, "Name: "); Texts.WriteString (w0, name); 
  156.             Texts.WriteLn (w0); Texts.Append (Oberon.Log, w0.buf)
  157.         ELSE
  158.             Dialogs.Error ("Dialog")
  159.         END
  160.     END GetName;
  161.     PROCEDURE GetCmd*;
  162.     (** writes the command of the object under the caret to the log viewer *)
  163.         VAR o: Dialogs.Object; p: Dialogs.Panel; cmd: ARRAY 64 OF CHAR;
  164.     BEGIN
  165.         DialogFrames.FindObject (o, p);
  166.         IF Dialogs.res = Dialogs.ok THEN
  167.             COPY (o.cmd, cmd); Texts.WriteString (w0, "Command: "); Texts.WriteString (w0, cmd); 
  168.             Texts.WriteLn (w0); Texts.Append (Oberon.Log, w0.buf)
  169.         ELSE
  170.             Dialogs.Error ("Dialog")
  171.         END
  172.     END GetCmd;
  173.     PROCEDURE GetInitCmd*;
  174.     (** writes the command of the marked dialog to the log viewer *)
  175.         VAR x, y: INTEGER; p: Dialogs.Panel; cmd: ARRAY 64 OF CHAR;
  176.     BEGIN
  177.         DialogFrames.GetCaretPosition (p, x, y); Dialogs.res := Dialogs.ok;
  178.         IF p # NIL THEN
  179.             COPY (p.cmd, cmd); Texts.WriteString (w0, "Command: "); Texts.WriteString (w0, cmd); 
  180.             Texts.WriteLn (w0); Texts.Append (Oberon.Log, w0.buf)
  181.         ELSE
  182.             Dialogs.res := Dialogs.noPanelSelected
  183.         END;
  184.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  185.     END GetInitCmd;
  186.     PROCEDURE GetPar*;
  187.     (** writes the component par of the item under the caret to the log viewer *)
  188.         VAR o: Dialogs.Object; p: Dialogs.Panel; par: ARRAY 64 OF CHAR;
  189.     BEGIN
  190.         DialogFrames.FindObject (o, p);
  191.         IF Dialogs.res = Dialogs.ok THEN
  192.             COPY (o.par, par); Texts.WriteString (w0, "Parameter: "); Texts.WriteString (w0, par); 
  193.             Texts.WriteLn (w0); Texts.Append (Oberon.Log, w0.buf)
  194.         ELSE
  195.             Dialogs.Error ("Dialog")
  196.         END
  197.     END GetPar;
  198.     PROCEDURE SetGrid*;    (** int | ^ *)
  199.     (** sets the grid to which mouse movements are restricted *)
  200.         VAR i: INTEGER; f: DialogFrames.Frame; v: Viewers.Viewer;
  201.     BEGIN
  202.         v := Oberon.MarkedViewer();
  203.         IF v.dsc.next IS DialogFrames.Frame THEN
  204.             f := v.dsc.next(DialogFrames.Frame);
  205.             In.Open; In.Int(i);
  206.             IF (In.Done) & (i <= DialogFrames.gridMax) & (i >= DialogFrames.gridMin) THEN
  207.                 f.grid := i; Dialogs.res := Dialogs.ok
  208.             ELSE
  209.                 Dialogs.res := Dialogs.wrongInput; Dialogs.Error ("Dialog")
  210.             END
  211.         END
  212.     END SetGrid;
  213.     PROCEDURE box (o: Dialogs.Object; VAR done: BOOLEAN);
  214.         VAR x, y, w, h: INTEGER;
  215.     BEGIN
  216.         IF ~o.selected THEN RETURN END;
  217.         o.GetDim (x, y, w, h);  y := ABS (y); 
  218.         IF x < X0 THEN X0 := x END;
  219.         IF X1 < x + w THEN X1 := x + w END;
  220.         IF y - h < Y0 THEN Y0 := y - h END;
  221.         IF Y1 < y THEN Y1 := y END
  222.     END box;
  223.     PROCEDURE EnumCopy (o: Dialogs.Object; VAR done: BOOLEAN);
  224.         VAR x, y, w, h: INTEGER; new: Dialogs.Object;
  225.     BEGIN
  226.         IF ~o.selected THEN RETURN END;  
  227.         new := NIL; o.Copy (new); new.SetName (""); new.UnSelect;
  228.         o.GetDim (x, y, w, h); new.SetDim (x + nx, y + ny, w, h, new.overlapping);
  229.         o.panel.Insert (new, new.overlapping);
  230.     END EnumCopy;
  231.     PROCEDURE Do*;
  232.         VAR o: Dialogs.Object;
  233.     BEGIN
  234.         o := Dialogs.editObject;
  235.         IF o # NIL THEN o.Update (Dialogs.cmdPanel) END
  236.     END Do; 
  237.     PROCEDURE Track (f: DialogFrames.Frame; keys: SET; x0, y0: INTEGER; o: Dialogs.Object);
  238.         VAR 
  239.             keys0, keysum: SET; new: Dialogs.Object; ch1, ch2: BOOLEAN; 
  240.             x, y, xh, yh, wh, hh, xdif, ydif, col, ox, oy, ow, oh: INTEGER; 
  241.     BEGIN 
  242.         col := Display.white; keys0 := keys; keysum := keys;
  243.         ch1 := FALSE; ch2 := FALSE; 
  244.         xdif := x0; ydif := y0; 
  245.         IF o # NIL THEN o.GetDim (xh, yh, wh, hh) ELSE xh := x0; yh := y0 END;
  246.         IF (keys0 = {MR}) & (o # NIL) THEN 
  247.             IF o.selected THEN o.UnSelect ELSE o.Select END
  248.         END;
  249.         REPEAT 
  250.             Input.Mouse (keys, x, y); keysum := keysum + keys; 
  251.             xdif := xdif DIV f.grid * f.grid; ydif := ydif DIV f.grid * f.grid;
  252.             x := x DIV f.grid * f.grid; y := y DIV f.grid * f.grid;
  253.             Oberon.DrawCursor (Oberon.Mouse, Oberon.Arrow, x, y);
  254.             IF (xdif # x) OR (ydif # y) THEN
  255.                 IF  (keys0 = {MM}) THEN
  256.                     IF (keysum = {MM}) THEN
  257.                         IF (o # NIL) & (~ o.selected) THEN
  258.                             o.GetDim (ox, oy, ow, oh);
  259.                             o.SetDim (ox - xdif + x, oy - ydif + y, ow, oh, FALSE)
  260.                         ELSE
  261.                             f.panel.MoveSelected (x - xdif, y - ydif)
  262.                         END;
  263.                         IF Dialogs.res = Dialogs.ok THEN ch1 := TRUE; xdif := x; ydif := y END
  264.                     ELSIF (keysum = {MM, ML}) & (o # NIL) THEN
  265.                         o.GetDim (ox, oy, ow, oh);
  266.                         o.SetDim (ox, oy, ow - xdif + x, oh - ydif + y, FALSE);
  267.                         IF Dialogs.res = Dialogs.ok THEN xdif := x; ydif := y; ch2 := TRUE END
  268.                     END; 
  269.                 ELSIF (keys0 = {MR}) & (o = NIL) THEN
  270.                     Display1.Line (f, col, x0, y0, x0, ydif, Display.invert); Display1.Line (f, col, x0, y0, xdif, y0, Display.invert);
  271.                     Display1.Line (f, col, x0, ydif, xdif, ydif, Display.invert); Display1.Line (f, col, xdif, y0, xdif, ydif, Display.invert);
  272.                     xdif := x; ydif := y;
  273.                     f.panel.Select (Min (x0 - f.X, xdif - f.X), Min (y0 - f.Y - f.H, ydif - f.Y - f.H), ABS (x0 - xdif), ABS (y0 - ydif));
  274.                     Display1.Line (f, col, x0, y0, x0, ydif, Display.invert); Display1.Line (f, col, x0, y0, xdif, y0, Display.invert);
  275.                     Display1.Line (f, col, x0, ydif, xdif, ydif, Display.invert); Display1.Line (f, col, xdif, y0, xdif, ydif, Display.invert);
  276.                 END;
  277.             END;
  278.         UNTIL keys = {};
  279.         IF (keys0 = {ML}) & (keysum = {ML}) THEN
  280.             Oberon.DrawCursor (Oberon.Mouse, Oberon.Arrow, x, y); 
  281.             Oberon.DrawCursor (Oberon.Pointer, reticule, x, y);
  282.             Oberon.PassFocus (Viewers.This (x, y));
  283.         ELSIF (keys0 = {ML}) & (keysum = {ML, MM}) THEN
  284.             X0 := MAX (INTEGER); X1 := MIN (INTEGER); Y0:= MAX (INTEGER); Y1 := MIN (INTEGER);
  285.             f.panel.Enumerate (box);
  286.             nx := (x - f.X) - X0; ny := (y - f.Y - f.H) + Y0; f.panel.Enumerate (EnumCopy)
  287.         ELSIF (keys0 = {MR}) & (keysum = {ML, MR}) & (o # NIL) THEN 
  288.             f.panel.Remove (o); f.panel.RemoveSelections  
  289.         ELSIF (keys0 = {MR}) & (keysum = {MM, MR}) & (o # NIL) THEN 
  290.                 o.UnSelect (); new := NIL; o.Copy (new);
  291.                 o.GetDim (ox, oy, ow, oh); new.SetName (""); new.SetDim (ox - x0 + x, oy - y0 + y, ow, oh, FALSE);
  292.                 f.panel.Insert (new, new.overlapping)
  293.         ELSIF (keys0 = {MR}) & (o=NIL) THEN
  294.             Display1.Line (f, col, x0, y0, x0, ydif, Display.invert); Display1.Line (f, col, x0, y0, xdif, y0, Display.invert);
  295.             Display1.Line (f, col, x0, ydif, xdif, ydif, Display.invert); Display1.Line (f, col, xdif, y0, xdif, ydif, Display.invert);
  296.             IF keysum = {MR, ML} THEN 
  297.                 f.panel.RemoveObjects (Min (x0 - f.X, xdif - f.X), Min (y0 - f.Y - f.H, ydif - f.Y - f.H), ABS (x0 - xdif), ABS (y0 - ydif));
  298.             END
  299.         ELSIF (keys0 = {MM}) & (keysum = {MM, MR}) & (o # NIL) THEN o.Edit ()
  300.         END;
  301.         IF (ch1) & (keysum # {MM}) & (keysum # {MM, ML})  THEN
  302.             IF (o # NIL ) & (~ o.selected) THEN
  303.                 o.GetDim (ox, oy, ow, oh); o.SetDim (xh, yh, ow, oh, FALSE)
  304.             ELSE
  305.                 f.panel.MoveSelected (xh - xdif, yh - ydif)
  306.             END
  307.         END;
  308.         IF (ch2) & (keysum # {MM, ML}) & (o # NIL) THEN
  309.             o.GetDim (xh, yh, ow, oh); o.SetDim (xh, yh, wh, hh, FALSE)
  310.         END;
  311.     END Track;
  312.     PROCEDURE Handle* (f: Display.Frame; VAR msg: Display.FrameMsg);
  313.     (** handles messages which were sent to the edit-frame f *)
  314.         VAR self: DialogFrames.Frame; o: Dialogs.Object;
  315.     BEGIN 
  316.         self := f (DialogFrames.Frame);
  317.         WITH msg: Oberon.InputMsg DO
  318.             IF msg.id = Oberon.consume THEN 
  319.                 IF msg.ch = CRSL THEN self.panel.MoveSelected (- self.grid, 0)
  320.                 ELSIF msg.ch = CRSR THEN self.panel.MoveSelected (self.grid, 0)
  321.                 ELSIF msg.ch = CRSD THEN self.panel.MoveSelected (0, - self.grid)
  322.                 ELSIF msg.ch = CRSU THEN self.panel.MoveSelected (0, self.grid)
  323.                 END
  324.             ELSIF (msg.id = Oberon.track) & (msg.keys # {}) THEN 
  325.                 o := self.panel.ThisObject (msg.X - self.X, msg.Y - self.Y - f.H);
  326.                 Track (self, msg.keys, msg.X, msg.Y, o)
  327.             ELSE 
  328.                 DialogFrames.Handle (f, msg)
  329.             END
  330.         | msg: Oberon.ControlMsg DO
  331.             IF (msg.id = Oberon.neutralize) THEN self.panel.RemoveSelections () END;
  332.             DialogFrames.Handle (f, msg)
  333.         ELSE 
  334.             DialogFrames.Handle (f, msg)
  335.         END
  336.     END Handle;
  337.     PROCEDURE Edit*;    (** name | ^ *)
  338.     (** opens a dialog viewer and displays the dialog from file name for editing *)
  339.         VAR name: ARRAY 32 OF CHAR; df: DialogFrames.Frame; v: Viewers.Viewer; x, y: INTEGER;
  340.             panel: Dialogs.Panel; file: Files.File; r: Files.Rider; m: TextFrames.Frame; t: Texts.Text; buf: Texts.Buffer;
  341.     BEGIN
  342.         In.Open; In.Name(name); panel := NIL;
  343.         IF In.Done THEN 
  344.             NEW(panel); file := Files.Old (name);
  345.             IF file # NIL THEN Files.Set (r, file, 0); panel.Load (r) END
  346.         END;
  347.         IF panel # NIL THEN
  348.             NEW(df); df.Open (Handle, panel); df.col := 11;
  349.             Oberon.AllocateUserViewer (Oberon.Mouse.X, x, y);
  350.             IF Files.Old ("Dialog.Menu.Text") = NIL THEN
  351.                 m := TextFrames.NewMenu (name, editMenu)
  352.             ELSE
  353.                 m := TextFrames.NewMenu (name, "");
  354.                 NEW (t); Texts.Open (t, "Dialog.Menu.Text");
  355.                 NEW (buf); Texts.OpenBuf (buf); Texts.Save (t, 0, t.len, buf); Texts.Append (m.text, buf)
  356.             END;
  357.             v := MenuViewers.New (m, df, TextFrames.menuH, x, y)
  358.         END
  359.     END Edit;
  360.     PROCEDURE Store*;
  361.     (** stores the dialog under the name appearing in its menu frame *)
  362.         VAR v: Viewers.Viewer; f: Files.File; r: Files.Rider; s: Texts.Scanner; name: ARRAY 64 OF CHAR;
  363.             t: Texts.Text; r2: Texts.Reader; ch: CHAR;
  364.     BEGIN 
  365.         v := Oberon.Par.vwr; name := "";
  366.         IF (v.dsc # Oberon.Par.frame) OR (v.dsc = NIL) OR (v.dsc.next = NIL) OR ~(v.dsc.next IS DialogFrames.Frame) THEN
  367.             v := Oberon.MarkedViewer ();
  368.             Texts.OpenScanner (s, Oberon.Par.text, Oberon.Par.pos); Texts.Scan (s);
  369.             IF (s.line = 0) & ((s.class = Texts.Name) OR (s.class = Texts.String)) THEN COPY (s.s, name) END
  370.         END;
  371.         IF (v.dsc # NIL) & (v.dsc.next # NIL) & (v.dsc.next IS DialogFrames.Frame) THEN
  372.             IF (name = "") & (v.dsc IS TextFrames.Frame) THEN
  373.                 Texts.OpenScanner (s, v.dsc(TextFrames.Frame).text, 0); Texts.Scan (s);
  374.                 IF (s.line = 0) & ((s.class = Texts.Name) OR (s.class = Texts.String)) THEN COPY (s.s, name) END
  375.             END;
  376.             IF name # "" THEN f := Files.New(name); Files.Set(r, f, 0);
  377.                 v.dsc.next(DialogFrames.Frame).panel.Store (r); 
  378.                 Files.Register (f);
  379.                 Texts.WriteString (w0, "Dialog.Store "); 
  380.                 Texts.WriteString (w0, name); Texts.WriteLn (w0);
  381.                 Texts.Append (Oberon.Log, w0.buf)
  382.             END;
  383.             t := v.dsc (TextFrames.Frame).text;
  384.             Texts.OpenReader (r2, t, t.len - 1); Texts.Read (r2, ch);
  385.             IF ch = "!" THEN Texts.Delete (t, t.len - 1, t.len) END
  386.         END
  387.     END Store;
  388.     PROCEDURE Print*;     (**  ^ | * | {name} ~ *) 
  389.     (** prints dialogs to print server named server *)
  390.         VAR s: Texts.Scanner; p: Dialogs.Panel; x, y, res: INTEGER; 
  391.             r: Files.Rider; file: Files.File; name: ARRAY 32 OF CHAR;
  392.         PROCEDURE PrintGetMainArg (VAR s: Texts.Scanner);
  393.         (* see implementation of module Edit *)
  394.             VAR text: Texts.Text; beg, end, time: LONGINT;
  395.         BEGIN
  396.             Texts.Scan (s);
  397.             IF (s.class = Texts.Char) & (s.c = "^") THEN 
  398.                 Oberon.GetSelection (text, beg, end, time);
  399.                 IF time >= 0 THEN Texts.OpenScanner (s, text, beg); Texts.Scan (s) END
  400.             END;
  401.             IF s.line # 0 THEN s.class := Texts.Inval END
  402.         END PrintGetMainArg;
  403.         PROCEDURE PrintError (res: INTEGER);
  404.         (* writes an error message to the log viewer *)
  405.         BEGIN
  406.             IF res = 1 THEN Texts.WriteString (w0, "Dialog Print Error 1: No connection")
  407.             ELSIF res = 2 THEN Texts.WriteString (w0, "Dialog Print Error 2: No link")
  408.             ELSIF res = 3 THEN Texts.WriteString (w0, "Dialog Print Error 3: Bad response")
  409.             ELSIF res = 4 THEN Texts.WriteString (w0, "Dialog Print Error 4: Wrong input")
  410.             ELSIF res = 5 THEN Texts.WriteString (w0, "Dialog Print Error 5: No panel selected")
  411.             END;
  412.             Texts.WriteLn (w0);
  413.             Texts.Append (Oberon.Log, w0.buf)
  414.         END PrintError;
  415.     BEGIN
  416.         Texts.OpenScanner (s, Oberon.Par.text, Oberon.Par.pos); Texts.Scan (s);
  417.         IF ((s.class = Texts.Name) OR (s.class = Texts.String)) & (s.line = 0) THEN
  418.             COPY (s.s, name); PrintGetMainArg (s); res := 0;
  419.             IF (s.class = Texts.Char) & (s.c = "*") THEN 
  420.                 DialogFrames.GetCaretPosition (p, x, y);
  421.             ELSIF s.class = Texts.Name THEN 
  422.                 file := Files.Old (s.s);
  423.                 IF file # NIL THEN 
  424.                     NEW (p); Files.Set (r, file, 0); p.Load (r); 
  425.                 ELSE
  426.                     res := 4
  427.                 END
  428.             ELSIF (Oberon.Par.vwr # NIL) & (Oberon.Par.vwr IS MenuViewers.Viewer) & (Oberon.Par.vwr.dsc.next IS DialogFrames.Frame) THEN
  429.                 p := Oberon.Par.vwr.dsc.next(DialogFrames.Frame).panel;
  430.             ELSE
  431.                 res := 4
  432.             END;
  433.             IF (p # NIL) & (res = 0) THEN
  434.                 Printer.Open (name, Oberon.User, Oberon.Password); res := Printer.res;
  435.                 IF res = 0 THEN
  436.                     p.Print (0, Printer.PageHeight); Printer.Page (1); Printer.Close     
  437.                 END
  438.             ELSE
  439.                 IF res # 4 THEN res := 5 END
  440.             END
  441.         ELSE 
  442.             res :=4
  443.         END;
  444.         IF res # 0 THEN PrintError (res) END;
  445.     END Print;
  446.     PROCEDURE DrawReticule (x, y: INTEGER);
  447.     BEGIN
  448.         IF x < CL THEN
  449.             IF x < markW THEN x := markW ELSIF x > DW THEN x := DW - markW END
  450.         ELSE
  451.             IF x < CL + markW THEN x := CL + markW ELSIF x > CL + DW THEN x := CL + DW - markW END
  452.         END;
  453.         IF y < markW THEN y := markW ELSIF y > DH THEN y := DH - markW END;
  454.         Display.CopyPattern (Display.white, Display.cross, x - markW, y - markW, 2)
  455.     END DrawReticule;
  456. BEGIN
  457.     DW := Display.Width - 8; DH := Display.Height - 8; CL := Display.ColLeft;
  458.     Texts.OpenWriter (w0); reticule.Draw := DrawReticule; reticule.Fade := DrawReticule;
  459. END Dialog.
  460.